// 11.1.1 函数对象的支持
// 函数对象(Function Objects)，也称为仿函数(Functors)，是C++泛型编程的基础组件。

// 函数对象的基本概念
// 函数对象是重载了operator()的类的实例，使其可以像函数一样被调用：
class Adder
{
public:
    Adder(int val) : value(val) {}

    int operator()(int x) const
    {
        return x + value;
    }

private:
    int value;
};

// 使用
Adder add5(5);
int result = add5(10); // 结果为15

// 函数对象的优势
// 1.可以有状态：
//      函数对象可以存储数据成员
//      普通函数无法保存状态（除非使用静态变量）
// 2.可以被参数化：
//      通过构造函数参数定制行为
//      提供更灵活的配置选项
// 3.编译时多态：
//      函数对象类型在编译时确定
//      允许编译器进行内联和优化
// 4.类型安全：
//      每个函数对象有自己的类型
//      便于类型检查和推导

// 标准库中的函数对象
// C++标准库提供了许多预定义的函数对象：

// 1.算术函数对象：
std::plus<int> add;
int sum = add(5, 3); // 结果为8

std::minus<int> subtract;
int difference = subtract(5, 3); // 结果为2

// 2.比较函数对象：
std::less<int> less;
bool result = less(3, 5); // 结果为true

std::greater<int> greater;
bool result2 = greater(5, 3); // 结果为true

// 3.逻辑函数对象：
std::logical_and<bool> logical_and;
bool result = logical_and(true, false); // 结果为false

std::logical_not<bool> logical_not;
bool result2 = logical_not(false); // 结果为true

// 在模板中使用函数对象
// 函数对象在泛型算法中特别有用：
template <typename Iterator, typename Predicate>
int count_if_value(Iterator begin, Iterator end, Predicate pred)
{
    int count = 0;
    for (Iterator it = begin; it != end; ++it)
    {
        if (pred(*it))
        {
            ++count;
        }
    }
    return count;
}

// 使用
std::vector<int> numbers = {1, 2, 3, 4, 5, 6};
int evenCount = count_if_value(numbers.begin(), numbers.end(),
                               [](int n)
                               { return n % 2 == 0; });

// 函数对象适配器
// C++提供了函数对象适配器，用于转换和组合函数对象：
// 1.std::bind：
void print(int x, int y)
{
    std::cout << x << ", " << y << std::endl;
}

auto printBound = std::bind(print, 42, std::placeholders::_1);
printBound(10); // 输出: 42, 10

// 2.std::not_fn (C++17)：
auto isOdd = [](int n)
{ return n % 2 == 1; };
auto isEven = std::not_fn(isOdd);
bool result = isEven(4); // 结果为true

// 函数对象是C++泛型编程的核心组件，它们提供了灵活、高效的方式来封装可调用的行为，特别适合用于STL算法和自定义泛型代码中。

